﻿using System;
using System.Collections.Generic;
using System.Yaml.Serialization;

namespace Reactor.ServiceGrid
{
    public class ServiceManifest
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceManifest"/> class.
        /// </summary>
        public ServiceManifest()
        {
            InstallAsWindowsService = true;
        }

        /// <summary>
        /// Gets or sets the service name.
        /// </summary>
        /// <value>The name.</value>
        public string ServiceName { get; set; }

        /// <summary>
        /// Gets or sets an id that uniquely identifies each service. This must 
        /// be the same identifier used in the database so the service can discover 
        /// it's own record.
        /// </summary>
        /// <value>The service id.</value>
        public int ServiceId { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [install as windows service].
        /// </summary>
        /// <value>
        /// 	<c>true</c> if [install as windows service]; otherwise, <c>false</c>.
        /// </value>
        public bool InstallAsWindowsService { get; set; }

        /// <summary>
        /// Gets or sets the executable path.
        /// </summary>
        /// <value>The executable path.</value>
        public string ExecutablePath { get; set; }

        /// <summary>
        /// Gets or sets the executable arguments.
        /// </summary>
        /// <value>The executable arguments.</value>
        public string ExecutableArguments { get; set; }

        /// <summary>
        /// Gets or sets the service part names.
        /// </summary>
        /// <value>The service part names.</value>
        public IList<string> RawServicePartIdentifiers { get; set; }

        /// <summary>
        /// Gets or sets the service description.
        /// </summary>
        /// <value>The description.</value>
        public string Description { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this service instance is a reactor core.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is reactor core; otherwise, <c>false</c>.
        /// </value>
        public bool IsReactorCore { get; set; }

        /// <summary>
        /// Saves this instance as an xml file at the specified path.
        /// </summary>
        /// <param name="path">The path.</param>
        public void Save(string path)
        {
            var yamlSerializer = new YamlSerializer();
            yamlSerializer.SerializeToFile(path, this);
        }

        /// <summary>
        /// Loads the xml from specified path, deserializes it, and returns a ServiceManifest instance.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns></returns>
        public static ServiceManifest Load(string path)
        {
            var yamlSerializer = new YamlSerializer();
            var deserializedObjects = yamlSerializer.DeserializeFromFile(path, new[] {typeof (ServiceManifest)});

            if (deserializedObjects.Length == 0) throw new InvalidOperationException(string.Format("Unable to deserialize service manifest from: {0}", path));

            return (ServiceManifest) deserializedObjects[0];
        }
    }
}
